/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of k3

	k3 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	k3 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with k3.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <shared.h>


/**
fs operations referrer for the kernel
*/

/**
Request DRIVER_START to all drivers
*/
static void main_Start_Drivers()
{
	struct fs *t;
	int e = 0;
	//Send start to all devices
	dprint(D_PROG, "drivers", "Starting");
	fsiter_parse(&t, "/drivers");
	e = fsiter_get_child(&t);
	while(!e) {
		dprint(D_PROG, t->name, "Starting driver");
		fs_write(NULL, t, NULL, DRIVER_START, 0);
		e = fsiter_get_next(&t);
	}
}

/**
Request DRIVER_START to all boot time modules after exporting kernel functions to them
*/
static void main_Start_Modules()
{
	struct fs *t;
	int e = 0;
	struct module_import *m;
	dprint(D_PROG, "modules", "Starting");
	fsiter_parse(&t, "/modules");
	e = fsiter_get_child(&t);
	while(!e) {
		dprint(D_PROG, t->name, "Starting module");
		m = (struct module_import *)t->buf.data;
		m->printk = printk;
		fs_write(NULL, t, NULL, DRIVER_START, 0);
		e = fsiter_get_next(&t);
	}
}

void _alloca()
{

}

void __main()
{

}

int kif_init(struct fs *this);
int main()
{
	//Displaying only progress messages
	dprint_set_debug(D_LEVEL_FREQ, "xmlp_", "", 0);
	arch_init();
	malloc_init();
	fs_init();
	sched_init();
	fsres_init();
	module_init();
	module_register();
	driver_init();
	device_register();
	main_Start_Drivers();
	main_Start_Modules();
	vmdrv_init();

	dprint(D_PROG, "kinterface", "Starting");

	dprint(D_PROG, "integrity", "Verifying");
	int err = malloc_verify();
	if(!err) {
		dprint(D_PROG, "memory zones", "Verified");
	}

	struct task *kinterface_task;
	kinterface_task = (struct task *)malloc_get(sizeof(struct task), "kift");
	struct fs *kinterface_task_fs = fs_create(FSFLAGS_DATA, "kinterface");
	kinterface_task->run = kif_init;
	kinterface_task_fs->buf.data = kinterface_task;
	kinterface_task_fs->buf.len = sizeof(struct task);
	kinterface_task_fs->buf.alloc_len = sizeof(struct task);
	fs_link(fsparse_get("/sched"), kinterface_task_fs);


	//Sleep
	fs_move(fsparse_get("/sched/waiting"), current->fs);

	fs_write(NULL, fsparse_get("/sched"), NULL, 0, 0);

	return 0;
}
